﻿using gt.framework.Configuration;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace gt.rediscachemanager.Configuration
{
    /// <summary>
    /// 缓存配置
    /// </summary>
    [XmlRoot("RedisCacheConfig")]
    public class RedisCacheConfig : ConfigBase
    {
        /// <summary>
        /// 应用缓存信息
        /// </summary>
        [XmlArray("ApplicationCaches"), XmlArrayItem("ApplicationCache")]
        public List<ApplicationCacheConfig> ApplicationCaches { get; set; }
        /// <summary>
        /// 缓存配置路径
        /// </summary>
        [XmlArray("CachePathMappings"), XmlArrayItem("CachePath")]
        public List<CachePathConfig> CachePathMappings { get; set; }
        /// <summary>
        /// 应用名称
        /// </summary>
        public string ApplicationName { get; set; }
        /// <summary>
        /// 所属IDC标识
        /// </summary>
        public string IDC { get; set; }

        #region override

        public override void ConfigChanged()
        {
            base.ConfigChanged();
        }
        public override string GetConfigFullPath()
        {
            return RedisConfigManager.GetRedisCacheConfigFullPath();
        }

        #endregion
    }
    public class CachePathConfig
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        [XmlAttribute("path")]
        public string Path { get; set; }
    }

    /// <summary>
    /// 应用缓存
    /// </summary>
    public class ApplicationCacheConfig
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        [XmlAttribute("main_cache")]
        public string MainCache { get; set; }
        [XmlAttribute("backup_cache")]
        public string BackupCache { get; set; }

        private BackupModeEnum backupMode = BackupModeEnum.None;
        /// <summary>
        /// 备用缓存切换功能开启
        /// </summary>
        public BackupModeEnum BackupMode { get { return backupMode; } set { backupMode = value; } }

        /// <summary>
        /// Redis重连后延迟恢复时间
        /// useful in MultipleAndBackup mode
        /// </summary>
        public int DelayedRecoverySeconds { get { return delayedRecoverySeconds; } set { delayedRecoverySeconds = value; } }
        private int delayedRecoverySeconds = -1;

        /// <summary>
        /// Redis主从切换最大等待时间
        /// useful in MultipleAndBackup mode
        /// </summary>
        public int RedisFailoverWaitSeconds { get { return redisFailoverWaitSeconds; } set { redisFailoverWaitSeconds = value; } }
        private int redisFailoverWaitSeconds = 10;

        public virtual string GetAppCacheName()
        {
            return this.Name;
        }
        public CachePoolConfig MainCachePool
        {
            get
            {
                if (string.IsNullOrEmpty(this.MainCache)) return null;
                return RedisConfigManager.GetCachePoolFromCache<CachePoolConfig>(this.MainCache);
            }
        }
        public CachePoolConfig BackupCachePool
        {
            get
            {
                if (string.IsNullOrEmpty(this.BackupCache)) return null;
                return RedisConfigManager.GetCachePoolFromCache<CachePoolConfig>(this.BackupCache);
            }
        }
    }

    /// <summary>
    /// 缓存池信息
    /// </summary>
    [XmlRoot("CachePool")]
    public class CachePoolConfig : ConfigBase
    {
        //public string Name { get; set; }
        public PoolMode Mode { get; set; }
        [XmlArray("Nodes"), XmlArrayItem("RedisNode")]
        public List<RedisNodeConfig> Nodes { get; set; }
    }

    public class RedisNodeConfig
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        public string Master { get; set; }
        public List<string> Slaves { get; set; }
        /// <summary>
        /// slot From
        /// useful in Multipler
        /// </summary>
        public int SlotFrom { get; set; }
        /// <summary>
        /// slot End
        /// useful in Multipler
        /// </summary>
        public int SlotTo { get; set; }

        /// <summary>
        /// Redis DB 库
        /// 默认-1
        /// </summary>
        private int db = -1;
        [XmlAttribute("db")]
        public int DB
        {
            get { return db; }
            set { db = value; }
        }

        /// <summary>
        /// 缓存Auth设置
        /// </summary>
        public string Auth { get; set; }

        public override string ToString()
        {
            StringBuilder s = new StringBuilder(Name);
            s.Append("(");
            string slaveIps = Slaves == null || Slaves.Count == 0 ? ""
                : string.Join(",", Slaves);
            s.Append(Master);
            if (!string.IsNullOrEmpty(slaveIps)) s.Append(",").Append(slaveIps);
            s.Append(")");
            return s.ToString();
        }
    }

    public enum PoolMode
    {
        /// <summary>
        /// 默认单点
        /// </summary>
        Single,
        /// <summary>
        /// 多点主从
        /// </summary>
        Multiple,
        /// <summary>
        /// Sentinel模式
        /// </summary>
        Sentinel
    }

    public enum BackupModeEnum
    {
        /// <summary>
        /// 默认 不切换也不同步
        /// </summary>
        None = 0,
        /// <summary>
        /// 主备切换
        /// </summary>
        Switch = 1,
        /// <summary>
        /// 同步数据
        /// </summary>
        Sync = 2,
        /// <summary>
        /// 主备切换且同步数据
        /// </summary>
        SwitchAndSync = 3
    }
}
